package org.example.servlet;

import org.example.DAO.UserDao;
import org.example.entity.User;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.example.impl.UserDaoImpl;
import org.example.Util.DataSourceUtil;
import org.example.Util.PasswordUtil;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@WebServlet("/Userregister")
public class UserregistrationServlet extends HttpServlet {
    private UserDao userDAO;

    @Override
    public void init() throws ServletException {
        super.init();
        try {
            DataSource dataSource = DataSourceUtil.getDataSource();
            this.userDAO = new UserDaoImpl(dataSource);
        } catch (Exception e) {
            throw new ServletException("初始化用户DAO失败", e);
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 设置请求编码
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");

        if (!ServletFileUpload.isMultipartContent(request)) {
            sendErrorResponse(request, response, "表单必须使用multipart/form-data编码");
            return;
        }

        FileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload upload = new ServletFileUpload(factory);
        InputStream avatarStream = null;

        try {
            List<FileItem> items = upload.parseRequest(request);
            Map<String, String> formFields = new HashMap<>();
            long avatarSize = 0;

            for (FileItem item : items) {
                if (item.isFormField()) {
                    formFields.put(item.getFieldName(), item.getString("UTF-8"));
                } else if ("avatar".equals(item.getFieldName())) {
                    if (item.getSize() > 0) {
                        avatarStream = item.getInputStream();
                        avatarSize = item.getSize();
                    }
                }
            }

            // 调试输出表单数据
            System.out.println("Received form data: " + formFields);

            Map<String, String> errors = validateRegistration(formFields);

            if (!errors.isEmpty()) {
                request.setAttribute("errors", errors);
                request.setAttribute("formData", formFields);
                request.getRequestDispatcher("Userregister.jsp").forward(request, response);
                return;
            }

            User user = new User();
            user.setUsername(formFields.get("username"));

            // 使用BCrypt加密密码
            String rawPassword = formFields.get("password");
            System.out.println("[DEBUG] 注册原始密码: " + rawPassword);
            String encryptedPassword = PasswordUtil.encryptPassword(rawPassword);
            System.out.println("[DEBUG] 加密后密码: " + encryptedPassword);
            user.setPassword(encryptedPassword);

            user.setGender(formFields.get("gender"));
            user.setEmail(formFields.get("email"));
            user.setPhone(formFields.get("phone"));

            if (avatarStream != null && avatarSize > 0) {
                if (avatarSize > 2 * 1024 * 1024) {
                    errors.put("avatarError", "头像大小不能超过2MB");
                    request.setAttribute("errors", errors);
                    request.setAttribute("formData", formFields);
                    request.getRequestDispatcher("Userregister.jsp").forward(request, response);
                    return;
                }
                user.setAvatar(avatarStream);
            }

            try {
                boolean registrationResult = userDAO.registerUser(user);
                if (registrationResult) {
                    System.out.println("[INFO] 用户注册成功: " + user.getUsername());
                    request.getSession().setAttribute("registerSuccess", "注册成功，请登录");
                    response.sendRedirect("Userlogin.jsp");
                    return;
                } else {
                    System.out.println("[ERROR] 用户注册失败: " + user.getUsername());
                    errors.put("generalError", "注册失败，请稍后再试");
                }
            } catch (SQLException e) {
                System.err.println("[ERROR] 注册数据库异常: " + e.getMessage());
                if (e.getMessage().contains("Duplicate entry") && e.getMessage().contains("username")) {
                    errors.put("usernameError", "用户名已被使用");
                } else if (e.getMessage().contains("Duplicate entry") && e.getMessage().contains("email")) {
                    errors.put("emailError", "邮箱已被注册");
                } else if (e.getMessage().contains("Duplicate entry") && e.getMessage().contains("phone")) {
                    errors.put("phoneError", "手机号已被注册");
                } else {
                    errors.put("databaseError", "数据库错误，请稍后再试");
                }
            }

            // 如果有错误，返回注册页面
            if (!errors.isEmpty()) {
                request.setAttribute("errors", errors);
                request.setAttribute("formData", formFields);
                request.getRequestDispatcher("Userregister.jsp").forward(request, response);
            }

        } catch (Exception e) {
            System.err.println("[ERROR] 注册过程异常: " + e.getMessage());
            e.printStackTrace();
            request.setAttribute("error", "处理请求时出错: " + e.getMessage());
            request.getRequestDispatcher("error.jsp").forward(request, response);
        } finally {
            if (avatarStream != null) {
                try {
                    avatarStream.close();
                } catch (IOException e) {
                    System.err.println("[ERROR] 关闭头像流失败: " + e.getMessage());
                }
            }
        }
    }

    private Map<String, String> validateRegistration(Map<String, String> formFields) {
        Map<String, String> errors = new HashMap<>();

        String username = formFields.get("username");
        if (username == null || username.trim().isEmpty()) {
            errors.put("usernameError", "用户名不能为空");
        } else if (!username.matches("\\w{4,16}")) {
            errors.put("usernameError", "用户名必须是4-16位字母数字下划线");
        }

        String password = formFields.get("password");
        if (password == null || password.trim().isEmpty()) {
            errors.put("passwordError", "密码不能为空");
        } else if (!password.matches("(?=.*\\d)(?=.*[a-zA-Z]).{6,18}")) {
            errors.put("passwordError", "密码必须是6-18位，包含字母和数字");
        }

        String email = formFields.get("email");
        if (email == null || email.trim().isEmpty()) {
            errors.put("emailError", "邮箱不能为空");
        } else if (!email.matches("^[\\w-.]+@([\\w-]+\\.)+[\\w-]{2,4}$")) {
            errors.put("emailError", "请输入有效的邮箱地址");
        }

        String phone = formFields.get("phone");
        if (phone == null || phone.trim().isEmpty()) {
            errors.put("phoneError", "手机号不能为空");
        } else if (!phone.matches("1[3-9]\\d{9}")) {
            errors.put("phoneError", "请输入有效的手机号");
        }

        String agreeTerms = formFields.get("agreeTerms");
        if (agreeTerms == null || !agreeTerms.equals("on")) {
            errors.put("agreeTermsError", "必须同意用户协议和隐私政策");
        }

        return errors;
    }

    private void sendErrorResponse(HttpServletRequest request, HttpServletResponse response, String message)
            throws ServletException, IOException {
        request.setAttribute("errorMessage", message);
        request.getRequestDispatcher("error.jsp").forward(request, response);
    }
}